﻿using System;
using System.IO;
using System.Net;
using System.Text;

namespace IomegaNas
{
    class Program
    {
        enum MyEnum { ShutDown, Restart, Blink, Info }

        static void Main(string[] args)
        {
            //Command Line Arguments parsings ---------------------------
            var c = new ConsoleCmdLine();
            var ip = new CmdLineString("host", true, "Ip/Host of the Iomega NAS (must be accesable by web browser)");
            var user = new CmdLineString("username", true, "Username (must be an Administrator)");
            var pass = new CmdLineString("password", true, "Password");
            var act = new CmdLineString("action", false, "Action (Allowed: \"Shutdown\", \"Restart\", \"Blink\", \"Information\"), Default: Information");
            c.RegisterParameter(ip);
            c.RegisterParameter(user);
            c.RegisterParameter(pass);
            c.RegisterParameter(act);
            c.Parse(args);

            //Defaults --------------------------------------------------
            MyEnum action;
            //Reading params --------------------------------------------
            switch (act.Value.Substring(0, 1))
            {
                case "s": action = MyEnum.ShutDown; break;
                case "r": action = MyEnum.Restart; break;
                case "b": action = MyEnum.Blink; break;
                /*case "i": */default: action = MyEnum.Info; break;
            }

            //Urls ------------------------------------------------------
            string url;
            string baseUrl = "https://" + ip;

            try
            {
                WRequest(baseUrl + "/index.html", null); //Request, first one, GET ***
            }
            catch (WebException we)
            {
                Console.WriteLine(we.Message);
                return;
            }
            WRequest(baseUrl + "/index.html", "hf_t=1&currentPage=index.html&visitedPages=index.html&login=" + user + "&passwordx=" + pass); //Request login ***
            WRequest(baseUrl + "/dashboard.html?t=1", null); //Request Navigate to Dashboard ***

            const string postAction = "hf_t=1&currentPage=dashboard.html&visitedPages=dashboard.html&restart=";
            string result = null;
            if (action == MyEnum.ShutDown)
            {
                url = baseUrl + "/dashboard.html?t=1";
                WRequest(url, postAction + "Poweroff"); //Request ***
            }
            if (action == MyEnum.Restart)
            {
                url = baseUrl + "/dashboard.html?t=1";
                WRequest(url, postAction + "Restart"); //Request ***
            }
            if (action == MyEnum.Blink)
            {
                url = baseUrl + "/dashboard.html?t=1";
                WRequest(url, postAction + "identifyDevice"); //Request ***
            }
            if (action == MyEnum.Info)
            {
                result = CleanInfo(WRequest(baseUrl + "/ajaxdashboard.html?t=1&au=dashboard.htm", null)); //xml used in ajax with info (ajax in web interface) ***
                result = result + "\n" + CleanEnviroment(WRequest(baseUrl + "/environmental.html", null)); //page with enviromental info ***
            }
            WRequest(baseUrl + "/logout.html", null); //LogOut (just for no leaving a web session open) ***
            if (result == null) result = "OK";
            Console.Write(result);
        }

        /// <summary>
        /// Cookies (conserve login from web session)
        /// </summary>
        static CookieCollection _cookies;

        /// <summary>
        /// Simplified Web Request function for connect to Iomega NAS
        /// </summary>
        public static string WRequest(string url, string post)
        {
            var request = (HttpWebRequest)WebRequest.Create(url);
            request.Credentials = CredentialCache.DefaultCredentials;
            request.CookieContainer = new CookieContainer();
            if (_cookies != null && _cookies.Count > 0) request.CookieContainer.Add(_cookies);
            //ServicePointManager.ServerCertificateValidationCallback = delegate(object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors){ return true; };
            ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
            if (post != null)
            {
                request.ContentType = "application/x-www-form-urlencoded";
                request.Method = "POST";
                byte[] byteArray = Encoding.UTF8.GetBytes(post);
                request.ContentLength = byteArray.Length;
                using (Stream dataStream = request.GetRequestStream()) //Request
                {
                    dataStream.Write(byteArray, 0, byteArray.Length);
                    dataStream.Close();
                }
            }
            string responseFromServer = null;
            using (WebResponse response = request.GetResponse()) //Response
            {
                var resp = (HttpWebResponse)response;
                if (resp.Cookies.Count > 0) _cookies = resp.Cookies;  //We save cookies for eat laters
                //Console.WriteLine(((HttpWebResponse)response).StatusDescription); //response code
                StreamReader reader = null;
                using (Stream dataStream = response.GetResponseStream())
                {
                    if (dataStream != null) reader = new StreamReader(dataStream);
                    if (reader != null)
                    {
                        responseFromServer = reader.ReadToEnd();
                    }
                }
                if (reader != null) reader.Close();
                response.Close();
            }
            return responseFromServer;
        }

        /// <summary>
        /// Informationn about size is retrieved in an xml format (used by an ajax call in web iterface)
        /// we clean it garbage to conserve clean text/info
        /// </summary>
        public static string CleanInfo(string info)
        {

            if (info.StartsWith("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n"))
                info = info.Remove(0, info.IndexOf("Status", StringComparison.Ordinal) + "Status ".Length);
            info = info.Remove(info.IndexOf("graph=", StringComparison.Ordinal));
            info = info.Replace("\" ", "\n");
            info = info.Replace("=\"", ": ");
            return "Status Info: \n" + info;
        }

        /// <summary>
        /// Enviromental Informationn about size system temperature, fan speed and voltage from html page
        /// we clean it garbage to conserve clean text/info
        /// </summary>
        public static string CleanEnviroment(string info)
        {
            string finalInfo = "Enviroment Info: \n";
            info = info.Remove(0, info.IndexOf("<h2 class=\"FormHead\">", StringComparison.Ordinal)); //Remove until
            info = info.Remove(info.IndexOf("<div class=\"FormBtn\">", StringComparison.Ordinal)); //Remove from
            info = info.Remove(0, info.IndexOf("<div class=\"StatTable\">", StringComparison.Ordinal)); //Remove until
            info = info.Remove(0, info.IndexOf("System", StringComparison.Ordinal)); //Remove until
            info = info.Replace("</span><span class=\"Value\">", ": "); //Remove HTML Tag
            finalInfo = finalInfo + info.Remove(info.IndexOf("<", StringComparison.Ordinal)) + "\n"; //Just First info
            info = info.Remove(0, info.IndexOf("<div class=\"StatTable\">", StringComparison.Ordinal)); //Remove until
            info = info.Remove(0, info.IndexOf("Internal Fan", StringComparison.Ordinal)); //Remove until
            finalInfo = finalInfo + info.Remove(info.IndexOf("<", StringComparison.Ordinal)) + "\n"; //Just First info
            info = info.Remove(0, info.IndexOf("<div class=\"StatTable\">", StringComparison.Ordinal)); //Remove until
            info = info.Remove(0, info.IndexOf("/> ", StringComparison.Ordinal) + "/> ".Length); //Remove until
            finalInfo = finalInfo + info.Remove(info.IndexOf("<", StringComparison.Ordinal)) + "\n"; //Just First info
            info = info.Remove(0, info.IndexOf("/> ", StringComparison.Ordinal) + "/> ".Length); //Remove until
            finalInfo = finalInfo + info.Remove(info.IndexOf("<", StringComparison.Ordinal)) + "\n"; //Just First info
            return finalInfo;
        }
    }

}
